﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

using System.Windows.Forms;
using NeuralNetwork;
using TheVoiceOfSnake;
using TheVoiceOfSnake.Models;
using TheVoiceOfSnake.Enums;
using System.Threading;
using TheVoiceOfSnake.BussinesLogic;

namespace DigitsRecognizer.UI
{
    public class GameForm : Form
    {
        private string Login = "test";
        private Label DescriptionLabel, PointsLabel, TimeLabel, CommandLabel;
        private Button CancelButton, StartButton, StopButton;
        private SpeechRecognizer Recognizer;
        private Direction Command = Direction.None;

        /* pola dla rozgrywki */
        private int Result, Time;                                // tablica przechowująca współrzędne planszy
        private GameField[,] GameBoard;                         //  pole gry
        private Graphics Surface;
        private Pen GreenPen, BluePen, BlackPen, WhitePen;
        private SolidBrush GreenBrush, BlueBrush, BlackBrush, WhiteBrush; /* pędzele do wypełnienia figury wewnątrz obiektu */
        private int Width, Height, SizeX = 40, SizeY = 40, NumOfColumns = 10, NumOfRows = 10;
        private Snake Snake;
        private GameField Gift;
        private MovesTrigger MovesTrigger;

        public GameForm() 
        {
            this.MinimumSize = new Size(600, 500);
            this.CenterToScreen();
            this.MinimizeBox = false;
            this.MaximizeBox = false;
            this.Text = string.Format("The Voice of Snake | User : {0}", Login);

            DescriptionLabel = new Label();
            DescriptionLabel.AutoSize = true;
            DescriptionLabel.Text = "The Voice \nof Snake";
            DescriptionLabel.Location = new Point(460, 12);
            DescriptionLabel.Font = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), 16, FontStyle.Italic);

            PointsLabel = new Label();
            PointsLabel.AutoSize = true;
            PointsLabel.Text = string.Format("Punkty:\n{0}", Result);
            PointsLabel.Location = new Point(460, 100);
            PointsLabel.Font = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), 11, FontStyle.Regular);

            TimeLabel = new Label();
            TimeLabel.AutoSize = true;
            TimeLabel.Text = string.Format("Czas:\n{0} s", Time);
            TimeLabel.Location = new Point(460, 160);
            TimeLabel.Font = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), 11, FontStyle.Regular);

            CommandLabel = new Label();
            CommandLabel.AutoSize = true;
            CommandLabel.Text = string.Format("Komenda:\n{0}", Commands.TransformCommandToString(Command));
            CommandLabel.Location = new Point(460, 220);
            CommandLabel.Font = new Font(new FontFamily(System.Drawing.Text.GenericFontFamilies.SansSerif), 11, FontStyle.Regular);

            StartButton = new Button();
            StartButton.Text = "Start";
            StartButton.Location = new Point(460, 290);

            StopButton = new Button();
            StopButton.Text = "Stop";
            StopButton.Location = new Point(460, 340);

            CancelButton = new Button();
            CancelButton.Text = "Powrót";
            CancelButton.Location = new Point(460, 390);

            this.Controls.Add(DescriptionLabel);
            this.Controls.Add(PointsLabel);
            this.Controls.Add(TimeLabel);
            this.Controls.Add(CommandLabel);
            this.Controls.Add(StopButton);
            this.Controls.Add(StartButton);
            this.Controls.Add(CancelButton);

            /* obsługa wciśnięcia przycisku Cancel */
            EventHandler cancelButtonEH = new EventHandler(OnClickCancel);
            CancelButton.Click += cancelButtonEH;

            /* obsługa wciśnięcia przycisku Start */
            EventHandler startButtonEH = new EventHandler(OnClickStart);
            StartButton.Click += startButtonEH;

            /* obsługa wciśnięcia przycisku Stop */
            EventHandler stopButtonEH = new EventHandler(OnClickStop);
            StopButton.Click += stopButtonEH;

            Recognizer = new SpeechRecognizer(this);
            Recognizer.IsGameMode(true);
            LoadBeginnigGameField();

            this.Paint += new PaintEventHandler(OnPaint);
            this.LocationChanged += new EventHandler(OnLocationChanged);
            this.Enter += new EventHandler(OnBeginningPaint);
        }

        public GameForm(string login)
            : this()
        {
            Login = login;
        }

        public void CheckParametersString(double estimationResult)
        {
            double result = estimationResult;
            Command = Commands.CheckResult(result);
            CommandLabel.Text = string.Format("Komenda:\n{0}", Commands.TransformCommandToString(Command));
            CommandLabel.Refresh();
            Snake.Turn(NumOfRows, NumOfColumns, Command, GameBoard);
        }

        private void ElementsAfterStart()
        {
            StartButton.Enabled = false;
            StopButton.Enabled = true;
        }

        private void ElementsAfterStop()
        {
            StartButton.Enabled = true;
            StopButton.Enabled = false;
        }

        private void SetRandomGift() 
        {
            //Gift = new GameField(1, 5);
            int x, y;
            Random r = new Random((int)DateTime.Now.Ticks);
            do
            {
                x = r.Next(0, NumOfColumns - 1);
                y = r.Next(0, NumOfRows - 1);
                Gift = new GameField(x, y);
            } while (Gift.FieldState != FieldState.Empty);          
        }

        private void SetBeginningSnake() 
        {
            // ustawienie węża na środku ekranu
            Snake = new Snake(4, 5, FieldState.SnakeHeadUp, 5, 5, FieldState.SnakeTailDown);
            GameBoard[Snake.Tail.X, Snake.Tail.Y].FieldState = Snake.Tail.State;
            GameBoard[Snake.Head.X, Snake.Head.Y].FieldState = Snake.Head.State;
        }

        private void StartGame() 
        {
            MovesTrigger = new MovesTrigger(this);
            MovesTrigger.Start();
        }

        private void StopGame()
        {
            MovesTrigger.Stop();
        }

        public void MoveUp()
        {
            GameBoard[Snake.Head.X, Snake.Head.Y].FieldState = FieldState.Empty;
            Snake.MoveHead(NumOfRows, NumOfColumns);
            Snake.MoveBodyAndTail(NumOfRows, NumOfColumns, GameBoard);
        }

        public void RefreshBoard() 
        {
            // tymczasowe !!!
            //Snake.Turn(NumOfRows, NumOfColumns, Direction.Down, GameBoard);
            
            Time++;
            TimeLabel.Text = string.Format("Czas:\n{0} s", Time);
            TimeLabel.Refresh();
            MoveUp();
            DrawSnakeAndGift();
            OnPaint(this, new PaintEventArgs(Surface, this.ClientRectangle));
        }

        private void CheckObjects() 
        {
            GameBoard[0, 0].FieldState = FieldState.SnakeTailUp;
            GameBoard[0, 1].FieldState = FieldState.SnakeTailDown;
            GameBoard[0, 2].FieldState = FieldState.SnakeTailRight;
            GameBoard[0, 3].FieldState = FieldState.SnakeTailLeft;
            GameBoard[0, 4].FieldState = FieldState.SnakeHeadUp;
            GameBoard[0, 5].FieldState = FieldState.SnakeHeadDown;
            GameBoard[0, 6].FieldState = FieldState.SnakeHeadRight;
            GameBoard[0, 7].FieldState = FieldState.SnakeHeadLeft;
            GameBoard[1, 0].FieldState = FieldState.SnakeBodyVertical;
            GameBoard[1, 1].FieldState = FieldState.SnakeBodyHorizontal;
            GameBoard[1, 2].FieldState = FieldState.SnakeBodyLeftUp;
            GameBoard[1, 3].FieldState = FieldState.SnakeBodyRightUp;
            GameBoard[1, 4].FieldState = FieldState.SnakeBodyLeftDown;
            GameBoard[1, 5].FieldState = FieldState.SnakeBodyRightDown;
            GameBoard[5, 5].FieldState = FieldState.Gift;
        }
        #region Drawing

        private void LoadBeginnigGameField() 
        {
            InitializeDrawObjects();
            FillBeginningGameField();
            SetRandomGift();
            SetBeginningSnake();
            DrawSnakeAndGift();
            DrawBackground();
            DrawElements();
        }

        private void InitializeDrawObjects() 
        {
            SetBoardSize();
            Surface = this.CreateGraphics();
            GreenPen = new Pen(Color.Green, 1.0f);
            BluePen = new Pen(Color.Blue, 1.0f);
            BlackPen = new Pen(Color.Black, 1.0f);
            WhitePen = new Pen(Color.White, 1.0f);
            GreenBrush = new SolidBrush(Color.Green);
            BlueBrush = new SolidBrush(Color.Blue);
            BlackBrush = new SolidBrush(Color.Black);
            WhiteBrush = new SolidBrush(Color.White);
        }

        private void FillBeginningGameField() 
        {
            GameBoard = new GameField[NumOfRows, NumOfColumns];
            int x = 0, y = SizeY;
            for (int i = 0; i < GameBoard.GetLength(0); i++) 
            {
                x = SizeX;
                for (int j = 0; j < GameBoard.GetLength(1); j++) 
                { 
                    GameBoard[i, j] = new GameField(x, y);
                    x += SizeX;
                }
                y += SizeY;
            }
        }

        private void DrawBackground()
        {
            Surface.FillRectangle(BlackBrush, GameBoard[0, 0].X - 2, GameBoard[0, 0].Y - 2, Width + 4, Height + 4);
            Surface.FillRectangle(WhiteBrush, GameBoard[0, 0].X, GameBoard[0, 0].Y, Width, Height);
            DrawMesh();
        }

        private void SetBoardSize() 
        {
            Width = NumOfColumns * SizeX;
            Height = NumOfRows * SizeY;
        }

        private void DrawMesh() 
        {
            for (int i = 0; i < GameBoard.GetLength(0); i++)
            {
                Surface.DrawLine(BlackPen, GameBoard[0, i].X, GameBoard[0, i].Y, GameBoard[NumOfRows - 1, i].X, GameBoard[NumOfRows - 1, i].Y + SizeY);
                Surface.DrawLine(BlackPen, GameBoard[i, 0].X, GameBoard[i, 0].Y, GameBoard[i, NumOfColumns - 1].X + SizeX, GameBoard[i, NumOfColumns - 1].Y);
            }
        }

        private void DrawElements() 
        {
            for (int i = 0; i < GameBoard.GetLength(0); i++)
            {
                for (int j = 0; j < GameBoard.GetLength(1); j++)
                {
                    switch (GameBoard[i, j].FieldState) 
                    {
                        case FieldState.Empty:
                            break;

                        case FieldState.Gift:
                            DrawGift(i, j);
                            break;

                        case FieldState.SnakeTailUp:
                            DrawSnakeTailUp(i, j);
                            break;

                        case FieldState.SnakeTailDown:
                            DrawSnakeTailDown(i, j);
                            break;

                        case FieldState.SnakeTailRight:
                            DrawSnakeTailRight(i, j);
                            break;

                        case FieldState.SnakeTailLeft:
                            DrawSnakeTailLeft(i, j);
                            break;

                        case FieldState.SnakeHeadUp:
                            DrawSnakeHeadUp(i, j);
                            break;

                        case FieldState.SnakeHeadDown:
                            DrawSnakeHeadDown(i, j);
                            break;

                        case FieldState.SnakeHeadRight:
                            DrawSnakeHeadRight(i, j);
                            break;

                        case FieldState.SnakeHeadLeft:
                            DrawSnakeHeadLeft(i, j);
                            break;

                        case FieldState.SnakeBodyVertical:
                            DrawSnakeBodyVertical(i, j);
                            break;

                        case FieldState.SnakeBodyHorizontal:
                            DrawSnakeBodyHorizontal(i, j);
                            break;

                        case FieldState.SnakeBodyLeftUp:
                            DrawSnakeBodyLeftUp(i, j);
                            break;

                        case FieldState.SnakeBodyRightUp:
                            DrawSnakeBodyRightUp(i, j);
                            break;

                        case FieldState.SnakeBodyLeftDown:
                            DrawSnakeBodyLeftDown(i, j);
                            break;

                        default:   // FieldState.SnakeBodyRightDown
                            DrawSnakeBodyRightDown(i, j);
                            break;
                    }
                }
            }
        }

        private void DrawSnakeAndGift() 
        {
            // zjedzenie prezentu
            if (Gift.X == Snake.Head.X && Gift.Y == Snake.Head.Y)
            {
                Result++;
                PointsLabel.Text = string.Format("Punkty:\n{0}", Result);
                PointsLabel.Refresh();
                SetRandomGift();
                Snake.AddPoint(NumOfRows, NumOfColumns);
            }

            // koniec gry
            if (Snake.Body.Any(b => b.X == Snake.Head.X && b.Y == Snake.Head.Y) || (Snake.Tail.X == Snake.Head.X && Snake.Tail.Y == Snake.Head.Y))
            {
                MessageBox.Show("Przegrana!", "Koniec gry", MessageBoxButtons.OK, MessageBoxIcon.Error);
                StopThreads(); 
                this.Close();
            }
            GameBoard[Gift.X, Gift.Y].FieldState = FieldState.Gift;
            GameBoard[Snake.Tail.X, Snake.Tail.Y].FieldState = Snake.Tail.State;
            GameBoard[Snake.Head.X, Snake.Head.Y].FieldState = Snake.Head.State;
            foreach (var body in Snake.Body) 
            {
                GameBoard[body.X, body.Y].FieldState = body.State;
            }
        }
        #endregion

        #region SnakeAndGifts
        private void DrawGift(int x, int y)
        {
            Surface.FillEllipse(BlueBrush, GameBoard[x, y].X + 5, GameBoard[x, y].Y + 5, GameBoard[x, y].Width - (GameBoard[x, y].Width / 4), GameBoard[x, y].Height - (GameBoard[x, y].Height / 4));
        }

        private void DrawSnakeTailUp(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillClosedCurve(GreenBrush, new Point[]{new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2),
                                                            new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4),
                                                            new Point((GameBoard[x, y].X + GameBoard[x, y].Width / 4) + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 2)},
                                                            System.Drawing.Drawing2D.FillMode.Alternate);
            
        }

        private void DrawSnakeTailDown(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillClosedCurve(GreenBrush, new Point[]{new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2),
                                                            new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, (GameBoard[x, y].Y + GameBoard[x, y].Height / 4)+ GameBoard[x, y].Height / 2),
                                                            new Point((GameBoard[x, y].X + GameBoard[x, y].Width / 4) + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 2)},
                                                            System.Drawing.Drawing2D.FillMode.Alternate);
        }

        private void DrawSnakeTailRight(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillClosedCurve(GreenBrush, new Point[]{new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4),
                                                            new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, (GameBoard[x, y].Y + GameBoard[x, y].Height / 4)+ GameBoard[x, y].Height / 2),
                                                            new Point((GameBoard[x, y].X + GameBoard[x, y].Width / 4) + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 2)},
                                                            System.Drawing.Drawing2D.FillMode.Alternate);

        }

        private void DrawSnakeTailLeft(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillClosedCurve(GreenBrush, new Point[]{new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2),
                                                            new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4),
                                                            new Point(GameBoard[x, y].X + GameBoard[x, y].Width / 2, (GameBoard[x, y].Y + GameBoard[x, y].Height / 4)+ GameBoard[x, y].Height / 2)},
                                                            System.Drawing.Drawing2D.FillMode.Alternate);
        }

        private void DrawSnakeHeadUp(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillEllipse(GreenBrush, GameBoard[x, y].X + 5, GameBoard[x, y].Y + 5, GameBoard[x, y].Width - (GameBoard[x, y].Width / 4), GameBoard[x, y].Height - (GameBoard[x, y].Height / 4));
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 10, GameBoard[x, y].Y + 20, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 20, GameBoard[x, y].Y + 20, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 12, GameBoard[x, y].Y + 20, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 22, GameBoard[x, y].Y + 20, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
        }

        private void DrawSnakeHeadDown(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillEllipse(GreenBrush, GameBoard[x, y].X + 5, GameBoard[x, y].Y + 5, GameBoard[x, y].Width - (GameBoard[x, y].Width / 4), GameBoard[x, y].Height - (GameBoard[x, y].Height / 4));
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 10, GameBoard[x, y].Y + 8, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 20, GameBoard[x, y].Y + 8, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 12, GameBoard[x, y].Y + 13, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 22, GameBoard[x, y].Y + 13, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
        }

        private void DrawSnakeHeadRight(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillEllipse(GreenBrush, GameBoard[x, y].X + 5, GameBoard[x, y].Y + 5, GameBoard[x, y].Width - (GameBoard[x, y].Width / 4), GameBoard[x, y].Height - (GameBoard[x, y].Height / 4));
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 10, GameBoard[x, y].Y + 9, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 10, GameBoard[x, y].Y + 19, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 15, GameBoard[x, y].Y + 11, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 15, GameBoard[x, y].Y + 21, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);

        }

        private void DrawSnakeHeadLeft(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillEllipse(GreenBrush, GameBoard[x, y].X + 5, GameBoard[x, y].Y + 5, GameBoard[x, y].Width - (GameBoard[x, y].Width / 4), GameBoard[x, y].Height - (GameBoard[x, y].Height / 4));
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 20, GameBoard[x, y].Y + 9, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(WhiteBrush, GameBoard[x, y].X + 20, GameBoard[x, y].Y + 19, GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 4);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 19, GameBoard[x, y].Y + 11, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
            Surface.FillEllipse(BlackBrush, GameBoard[x, y].X + 19, GameBoard[x, y].Y + 21, GameBoard[x, y].Width / 8, GameBoard[x, y].Height / 8);
        }

        private void DrawSnakeBodyVertical(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y, GameBoard[x, y].Width / 2, GameBoard[x, y].Height);

        }

        private void DrawSnakeBodyHorizontal(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width, GameBoard[x, y].Height / 2);
        }

        private void DrawSnakeBodyLeftUp(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2 + GameBoard[x, y].Height / 4);
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width /2 , GameBoard[x, y].Height / 2);
        }

        private void DrawSnakeBodyRightUp(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2 + GameBoard[x, y].Height / 4);
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
        }

        private void DrawSnakeBodyLeftDown(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 2, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2 + GameBoard[x, y].Width / 4, GameBoard[x, y].Height / 2);
        }

        private void DrawSnakeBodyRightDown(int x, int y)
        {
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 4, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2 + GameBoard[x, y].Height / 4);
            Surface.FillRectangle(GreenBrush, GameBoard[x, y].X + GameBoard[x, y].Width / 2, GameBoard[x, y].Y + GameBoard[x, y].Height / 4, GameBoard[x, y].Width / 2, GameBoard[x, y].Height / 2);
        }
        #endregion


        #region Events
        private void OnClickCancel(object sender, EventArgs args)
        {
            if (MovesTrigger != null)
            {
                StopThreads();
            }   
            this.Close();
        }

        private void OnClickStart(object sender, EventArgs args)
        {
            Recognizer.SetLogin(Login);
            Recognizer.StartCapturing();
            Recognizer.Start();
            StartGame();
            ElementsAfterStart();
        }

        private void OnClickStop(object sender, EventArgs args)
        {
            StopThreads(); 
            ElementsAfterStop();
        }
        public void OnPaint(object sender, PaintEventArgs e)
        {
            DrawBackground();
            DrawElements();
        }

        public void OnLocationChanged(object sender, EventArgs e)
        {
            OnPaint(this, new PaintEventArgs(Surface, this.ClientRectangle));
        }

        public void OnBeginningPaint(object sender, EventArgs e)
        {
            this.Paint -= new PaintEventHandler(OnPaint);
        }

        private void StopThreads() 
        {
            Recognizer.Stop();
            Recognizer.StopCapturing();
            StopGame();
        }
        #endregion
    }
}
